package main

import (
	"context"
	"fmt"
	clientv3 "go.etcd.io/etcd/client/v3"
	"time"
)

// 先打开这个watch，再执行ops_for_watch
func main() {
	/*
				Watch watches on a key or prefix. watch一个key或者前缀。
				被观察的事件会进入通道。如果等待进入通道的revisions是被压缩了的，该watch会被server取消，客户端会发送一个压缩错误响应，通道也会被关闭。
				如果请求的revision是0或者未指定，通道会返回服务器接到请求之后的事件。
				如果ctx被取消了或者超时了，通道会关闭，此时来自通道的WatchResponse既没有事件也没有error。
				一旦watcher不再被使用，那么ctx必须被取消以释放资源。
				The watched events will be returned through the returned channel.
			If revisions waiting to be sent over the watch are compacted, then the watch will be canceled by the server, the client will post a compacted error watch response, and the channel will close.
			If the requested revision is 0 or unspecified, the returned channel will return watch events that happen after the server receives the watch request.
			If the context "ctx" is canceled or timed out, returned "WatchChan" is closed, and "WatchResponse" from this closed channel has zero events and nil "Err()".
			The context "ctx" MUST be canceled, as soon as watcher is no longer being used, to release the associated resources.

				如果ctx是  "context. Background/ TODO"，那么除非遇到不可恢复的异常（如ErrCompacted），否则通道不会关闭，且会一直阻塞到下次事件。
				例如，当ctx与"WithRequireLeader"一起使用时，如果server还没有leader（可能是因为网络分区），那会返回error "etcdserver: no leader" (ErrNoLeader)，然后通道会被关闭，且Err()非nil。
				为了避免在分区节点阻塞住，务必使用"WithRequireLeader"。
				If the context is "context. Background/ TODO", returned "WatchChan" will not be closed and block until event is triggered, except when server returns a non-recoverable error (e. g. ErrCompacted).
			For example, when context passed with "WithRequireLeader" and the connected server has no leader (e. g. due to network partition), error "etcdserver: no leader" (ErrNoLeader) will be returned, and then "WatchChan" is closed with non-nil "Err()".
			In order to prevent a watch stream being stuck in a partitioned node, make sure to wrap context with "WithRequireLeader".

				其他情况，只要ctx没超时或者取消，watch会一直重试其他错误，直到重连成果。
				Otherwise, as long as the context has not been canceled or timed out, watch will retry on other recoverable errors forever until reconnected.

		TODO: explicitly set context error in the last "WatchResponse" message and close channel? Currently, client contexts are overwritten with "valCtx" that never closes. TODO(v3.4): configure watch retry policy, limit maximum retry number (see https:// github. com/ etcd-io/ etcd/ issues/ 8980 )
	*/

	ctx, _ := context.WithTimeout(context.Background(), 25*time.Second)
	ctx2 := clientv3.WithRequireLeader(ctx) //
	watcher := CLI.Watch(ctx2, "/a/b/c")    //可以设置观察的事件
	for ws := range watcher {
		fmt.Println(ws.Events)
		err := ws.Err()
		if err != nil {
			fmt.Println(err)
		}
		for _, ev := range ws.Events {
			fmt.Printf("got: %s %q %q\n", ev.Type, ev.Kv.Key, ev.Kv.Value)
		}
	}

}
